package com.itheima.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.article.feign.ApAuthorFeign;
import com.itheima.article.pojo.ApAuthor;
import com.itheima.common.constants.BusinessConstants;
import com.itheima.common.exception.LeadNewsException;
import com.itheima.common.vo.PageResultVo;
import com.itheima.common.vo.ResultVo;
import com.itheima.user.dto.ApUserRealnameAuthDto;
import com.itheima.user.dto.ApUserRealNamePageRequestDto;
import com.itheima.user.mapper.ApUserMapper;
import com.itheima.user.pojo.ApUser;
import com.itheima.wemedia.feign.WmUserFeign;
import com.itheima.wemedia.pojo.WmUser;
import com.itheima.user.pojo.ApUserRealname;
import com.itheima.user.mapper.ApUserRealnameMapper;
import com.itheima.user.service.ApUserRealnameService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.xml.bind.PrintConversionEvent;
import java.time.LocalDateTime;

/**
 * @description <p>APP实名认证信息 业务实现</p>
 *
 * @version 1.0
 * @package com.itheima.user.service.impl
 */
@Slf4j
@Service
public class ApUserRealnameServiceImpl extends ServiceImpl<ApUserRealnameMapper, ApUserRealname> implements ApUserRealnameService {

    @Resource
    private ApUserMapper apUserMapper;

    @Resource
    private WmUserFeign wmUserFeign;

    @Resource
    private ApAuthorFeign apAuthorFeign;

    /**
     * 实名认证列表分页查询
     *
     * @param dto
     * @return
     */
    @Override
    public PageResultVo findPage(ApUserRealNamePageRequestDto dto) {
        //1. 设置分页参数
        IPage<ApUserRealname> pageInfo = new Page<>(dto.getPage(),dto.getSize());
        //2. 设置查询条件
        LambdaQueryWrapper<ApUserRealname> lqw = new LambdaQueryWrapper<>();
        lqw.eq(null != dto.getStatus(),ApUserRealname::getStatus,dto.getStatus());
        //3. 执行查询
        page(pageInfo, lqw);
        //4. 封装数据返回
        return PageResultVo.pageResult(dto.getPage(),dto.getSize(),pageInfo.getTotal(),pageInfo.getRecords());
    }

    /**
     * 实名认证  驳回
     *
     * @param dto
     */
    @Override
    public void authFail(ApUserRealnameAuthDto dto) {
        // 通过id查询记录
        ApUserRealname userRealname = getById(dto.getId());
        if (userRealname == null){
            log.error("实名认证非法操作，查询记录不存在！");
            throw new LeadNewsException("待审核的数据不存在，请重新操作！");
        }
        // 存在，还要判断状态，只能操作状态值为1的记录(待审核)
        if (userRealname.getStatus() != BusinessConstants.ApUserRealnameConstants.AUTH_WAITING){
            log.error("实名认证非法操作，查询记录不存在！");
            throw new LeadNewsException("待审核的数据不存在，请重新操作！");
        }
        // 执行更新操作
        //1. 创建一个新的实名认证对象
        ApUserRealname apUser = new ApUserRealname();
        //2. 设置实名认证的状态值
        apUser.setStatus(BusinessConstants.ApUserRealnameConstants.AUTH_REJECT);
        apUser.setReason(dto.getMsg());
        apUser.setUpdatedTime(LocalDateTime.now());
        //3. 设置更新条件
        apUser.setId(dto.getId());
        //4. 更新至数据库中
        updateById(apUser);
    }

    /**
     * 实名认证  通过
     *
     * @param dto
     */
    @Override
    @Transactional
    public void authPass(ApUserRealnameAuthDto dto) {
        // 查询user_id, 通过实名认证表记录中就有这个字段user_id
        Long id = dto.getId();
        ApUserRealname apUserRealname = getById(id);
        //1. 更新实名认证表记录的状态
        updateApUserRealNamePass(apUserRealname);
        //2. 更新用户表的flag与是否认证过
        updateApUserInfo(id);
        //3. 添加自媒体账号
        WmUser wmUser = createWmUser(apUserRealname.getUserId());
        //4. 添加作者
        createApAuthor(wmUser);
        //5. 事务控制
    }

    /**
     * 创建作者信息
     * @param wmUser
     */
    private void createApAuthor(WmUser wmUser) {
        //1. 通过wmUserId和apUserId查询作者账号是否存在
        Long wmUserId = wmUser.getId();
        Long apUserId = wmUser.getApUserId();
        ResultVo<ApAuthor> getResult = apAuthorFeign.getByApUserIdWmUserId(apUserId, wmUserId);
        // 解析结果
        if (!getResult.isSuccess()) {
            log.error("远程调用文章微服查询作者信息失败:{}", getResult.getErrorMessage());
            throw new LeadNewsException("操作失败, 请求稍后重试!");
        }
        //3. 获取作者对象，并判断是否存在
        ApAuthor author = getResult.getData();
        if (null == author){
            //4. 添加作者记录
            author = new ApAuthor();
            author.setName(wmUser.getName());
            author.setUserId(apUserId);
            author.setWmUserId(wmUserId);
            author.setType(BusinessConstants.ApAuthorConstants.A_MEDIA_USER);
            author.setCreatedTime(LocalDateTime.now());
            // 远程调用
            ResultVo<ApAuthor> addResult = apAuthorFeign.add(author);
            // 解析结果
            if (!addResult.isSuccess()) {
                log.error("远程调用文章微服添加作者信息失败:{}", getResult.getErrorMessage());
                throw new LeadNewsException("操作失败, 请求稍后重试!");
            }
        }
    }

    /**
     * 添加自媒体账号
     * @param apUserId
     */
    private WmUser createWmUser(Long apUserId) {
        //1. 通过apUserId查询自媒体账号是否存在
        ResultVo<WmUser> getResult = wmUserFeign.getByApUserId(apUserId);
        //2. 解析结果
        if (!getResult.isSuccess()) {
            // 远程调用失败了
            log.error("远程调用自媒体查询自媒体用户信息失败:{}", getResult.getErrorMessage());
            throw new LeadNewsException("操作失败, 请求稍后重试!下次再来");
        }
        //3. 获取自媒体对象，并判断是否存在
        WmUser wmUser = getResult.getData();
        //4. 不存在则添加自媒体对象
        if (wmUser == null) {
            // 构建自媒体账号
            wmUser = bulidWmUser(apUserId);
            // 远程调用添加
            ResultVo<WmUser> addResult = wmUserFeign.add(wmUser);
            // 解析结果
            if (!addResult.isSuccess()) {
                log.error("远程调用自媒体添加自媒体用户信息失败:{}", getResult.getErrorMessage());
                throw new LeadNewsException("操作失败, 请求稍后重试!");
            }
            // 获取新增的自媒体账号
            wmUser = addResult.getData();
        }
        return wmUser;
    }

    /**
     * 构建WmUser对象
     * @param apUserId
     * @return
     */
    private WmUser bulidWmUser(Long apUserId) {
        WmUser wmUser = new WmUser();
        //1. 通过apUserId查询app用户信息
        ApUser apUser = apUserMapper.selectById(apUserId);
        //2. 相同的属性直接拷贝
        BeanUtils.copyProperties(apUser,wmUser);
        //3. 特殊属性处理
        wmUser.setId(null);
        wmUser.setNickname(apUser.getName());
        wmUser.setStatus(BusinessConstants.WmUserConstants.STATUS_OK);
        if (apUser.getFlag() == BusinessConstants.ApUserConstants.FLAG_WEMEDIA){
            wmUser.setType(BusinessConstants.WmUserConstants.TYPE_PERSONAL);
        }
        wmUser.setScore(0);
        wmUser.setCreatedTime(LocalDateTime.now());
        wmUser.setApUserId(apUserId);
        return wmUser;
    }

    /**
     * 更新app用户表信息
     * @param apUserId
     */
    private void updateApUserInfo(Long apUserId) {
        //1. 创建更新pojo对象
        ApUser updatePojo = new ApUser();
        //2. 设置属性
        updatePojo.setFlag(BusinessConstants.ApUserConstants.FLAG_WEMEDIA);
        updatePojo.setIsIdentityAuthentication(BusinessConstants.ApUserConstants.AUTHENTICATED);
        //3. 设置条件
        updatePojo.setId(apUserId);
        //4. 执行更新
        apUserMapper.updateById(updatePojo);
    }

    /**
     *更新实名认证记录
     * @param apUserRealname
     */
    private void updateApUserRealNamePass(ApUserRealname apUserRealname) {
        // 不存在则报错
        if (apUserRealname == null){
            log.error("实名认证非法操作，查询记录不存在！");
            throw new LeadNewsException("待审核的数据不存在，请重新操作！");
        }
        // 存在，还要判断状态，只能操作状态值为1的记录(待审核)
        if (apUserRealname.getStatus() != BusinessConstants.ApUserRealnameConstants.AUTH_WAITING){
            log.error("实名认证非法操作，查询记录不存在！");
            throw new LeadNewsException("待审核的数据不存在，请重新操作！");
        }
        // 执行更新操作
        //1. 创建一个新的实名认证对象
        ApUserRealname updatePojo = new ApUserRealname();
        //2. 设置实名认证的状态值
        updatePojo.setStatus(BusinessConstants.ApUserRealnameConstants.AUTH_PASS);
        updatePojo.setUpdatedTime(LocalDateTime.now());
        //3. 设置更新条件
        updatePojo.setId(apUserRealname.getId());
        //4. 更新至数据库中
        updateById(updatePojo);
    }


}
